<?php

    #-------------------------------------------------------------#
	# This file is part of the Tekuna MVC Microframework for PHP. #
	# (c) 2009 Niels Jäckel <niels.jaeckel@tekuna.org>            #
	# Please visit http://tekuna.org/ for more information.       #
	#                                                             #
	# This software is licensed under the MIT License. Please     #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#


	class ViewTest extends AbstractTekunaTestCase {


		protected function getViewInstance($sViewType, $sExtension) {

			// get view instance
			$objView = new $sViewType();
			$objView -> setTemplateBaseDir(APPLICATION_ROOT . DIRECTORY_SEPARATOR . 'testTemplates' . DIRECTORY_SEPARATOR);
			$objView -> setTemplate("test$sViewType.$sExtension");

			return $objView;
		}


		public function testAbstractView() {

			// get view instance
			$objView = new SimpleView();

			// test getters and setters
			$objView -> setTemplateBaseDir(APPLICATION_ROOT);
			$this -> assertIdentical($objView -> getTemplateBaseDir(), APPLICATION_ROOT);

			$sMyTemplate = 'ATemplate.tpl';
			$objView -> setTemplate($sMyTemplate);
			$this -> assertIdentical($objView -> getTemplate(), $sMyTemplate);

			// test value assignments
			$objView -> assign('key1', 'value1');
			$objView -> assign('key2', 'value2');
			$objView -> assign('key3', 'value3');

			// test full value list
			$this -> assertIdentical($objView -> getAllValues(), array('key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'));

			// test single value request
			$this -> assertIdentical($objView -> getAssignedValue('key2'), 'value2');
			$this -> assertIdentical($objView -> getAssignedValue('nonExistentKey'), NULL);
		}


		public function testSimpleView() {

			// get view instance
			$objView = $this -> getViewInstance('SimpleView', 'tpl');

			// assign values
			$objView -> assign('key1', 'value1');
			$objView -> assign('key2', 'value2');

			// check simple scalar replacements
			$this -> assertIdentical($objView -> process(), "key1: value1\nkey2: value2");



			// get view instance
			$objView = $this -> getViewInstance('SimpleView', 'allvalues.tpl');

			// assign values
			$objView -> assign('key1', 'value1');
			$objView -> assign('key2', 'value2');

			// check all values list
			$this -> assertIdentical($objView -> process(), "{key1} = value1<br />\n{key2} = value2<br />\n");



			// get view instance
			$objView = $this -> getViewInstance('SimpleView', 'arraytest.tpl');

			// assign values
			$objView -> assign('this.is.no.array', 'scalar value');
			$objView -> assign('array', array('key1' => 'value1', 'key2' => 'value2'));
			$objView -> assign('array.nesting.test', array('key_1' => 'value_1', 'key_2' => 'value_2'));

			// check array replacements
			$this -> assertIdentical($objView -> process(), "scalar: scalar value\narray: [value1, value2]\narray nesting test: [value_1, value_2]");



			// get view instance
			$objView = $this -> getViewInstance('SimpleView', 'objecttest.tpl');

			// build test classes
			$obj1 = new stdClass();
			$obj1 -> key1 = 'value1';
			$obj1 -> key2 = 'value2';

			$obj2 = new stdClass();
			$obj2 -> key_1 = 'value_1';
			$obj2 -> key_2 = 'value_2';

			// assign values
			$objView -> assign('this.is.no.object', 'scalar value');
			$objView -> assign('object', $obj1);
			$objView -> assign('object.nesting.test', $obj2);

			// check object replacements
			$this -> assertIdentical($objView -> process(), "scalar: scalar value\nobject: [value1, value2]\nobject nesting test: [value_1, value_2]");



			// get view instance
			$objView = $this -> getViewInstance('SimpleView', 'nonExistentTemplate.tpl');

			// check exceptions
			try {

				$objView -> process();
				$this -> fail();
			}
			catch (TemplateNotFoundException $e) {

				$this -> pass();
			}
		}


		public function testPHPView() {

			// get view instance
			$objView = $this -> getViewInstance('PHPView', 'php');

			// assign test values
			$objView -> assign('key1', 'value1');
			$objView -> assign('key2', 'value2');

			// test scalars
			$this -> assertIdentical($objView -> process(), "key1: value1key2: value2");



			// get view instance
			$objView = $this -> getViewInstance('PHPView', 'arraytest.php');

			// assign test values
			$objView -> assign('a1', array('a', 'b', 'c'));
			$objView -> assign('a2', array('i' => 'iii', 'j' => 'jjj'));

			// test arrays
			$this -> assertIdentical($objView -> process(), "a1: abca2: iiijjj");



			// get view instance
			$objView = $this -> getViewInstance('PHPView', 'objecttest.php');

			// build test objects
			$obj1 = new stdClass();
			$obj1 -> foo = 'foo123';
			$obj1 -> bar = 'bar321';

			// assign test values
			$objView -> assign('o1', $obj1);

			// test objects
			$this -> assertIdentical($objView -> process(), "foo123bar321");



			// get view instance
			$objView = $this -> getViewInstance('PHPView', 'arrayasobjecttest.php');

			// assign test values
			$objView -> assignArrayAsObjectTree('a1', array('foo' => 'myFoo', 'bar' => 'myBar'));

			// test arrays as objects
			$this -> assertIdentical($objView -> process(), 'myFoomyBar');


			// get view instance
			$objView = $this -> getViewInstance('PHPView', 'nonExistentTemplate');

			// test wrong template exception
			try {

				$objView -> process();
				$this -> fail();
			}
			catch (TemplateNotFoundException $e) {

				$this -> pass();
			}

			// test illegal object arguments
			try {

				$objView -> assignArrayAsObjectTree('a1', array('%foo' => 'myFoo'));
				$this -> fail();
			}
			catch (InvalidArgumentException $e) {

				$this -> pass();
			}
		}


		public function testXSLTView() {

			// get view instance
			$objView = $this -> getViewInstance('XSLTView', 'xsl');

			// assign test variables
			$obj = new stdClass();
			$obj -> a = 'AAA';
			$obj -> b = 'BBB';
			$obj -> c = 'CCC';

			$objView -> assign('scalar.integer', 4);
			$objView -> assign('scalar.float', 3,2);
			$objView -> assign('scalar.string', 'myString');
			$objView -> assign('structure.array', array('foo', 'bar', 'baz'));
			$objView -> assign('structure.object', $obj);

			// test output
			$sExpectedOutput = "<output><scalar><integer>4</integer><float>3</float><string>myString</string></scalar><structure><array><structure.array>foo</structure.array><structure.array>bar</structure.array><structure.array>baz</structure.array></array><object><a>AAA</a><b>BBB</b><c>CCC</c></object></structure></output>\n";
			$this -> assertIdentical($objView -> process(), $sExpectedOutput);



			// get view instance
			$objView = $this -> getViewInstance('XSLTView', 'copyInput.xsl');

			// assign test variables
			$obj = new stdClass();
			$obj -> a = 'AAA';
			$obj -> b = 'BBB';
			$obj -> c = 'CCC';

			$objView -> assign('scalar.integer', 4);
			$objView -> assign('scalar.float', 3,2);
			$objView -> assign('scalar.string', 'myString');
			$objView -> assign('structure.array', array('foo', 'bar', 'baz'));
			$objView -> assign('structure.object', $obj);

			// test output of test data xml
			$sExpectedOutput = "<data>\n\t<scalar.integer>4</scalar.integer>\n\t<scalar.float>3</scalar.float>\n\t<scalar.string>myString</scalar.string>\n\t<structure.array>foo</structure.array>\n\t<structure.array>bar</structure.array>\n\t<structure.array>baz</structure.array>\n\t<structure.object>\n\t\t<a>AAA</a>\n\t\t<b>BBB</b>\n\t\t<c>CCC</c>\n\t</structure.object>\n</data>\n";
			$this -> assertIdentical($objView -> process(), $sExpectedOutput);



			// test bad formatted XSLT
			$objView = $this -> getViewInstance('XSLTView', 'badformatted.xsl');

			try  {

				$objView -> process();
				$this -> fail();
			}
			catch (XSLTViewException $e) {

				$this -> pass();
			}


			// test template exception
			$objView = $this -> getViewInstance('XSLTView', 'nonExistentTemplate.xsl');

			try  {

				$objView -> process();
				$this -> fail();
			}
			catch (TemplateNotFoundException $e) {

				$this -> pass();
			}
		}
	}



